using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
using System.Reflection;
using Sinacor.Infra.Service.Data;

namespace Sinacor.Infra.Service.Security.Services
{
    [AttributeUsage((AttributeTargets.Method))]
    public sealed class TransactionRequiredAttribute : Attribute, IOperationBehavior
    {

        public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) {
            
        }
        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) {

        }
        public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
        {
            dispatchOperation.ParameterInspectors.Add(new SinacorParameterInspector());
        }

        public void Validate(OperationDescription operationDescription) { 
        
        }
 
    }

    public sealed class SinacorParameterInspector : IParameterInspector
    {

        #region IParameterInspector Members

        public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
        {
            TransactionCollection objCollection = TransactionCollection.GetInstance();

            int companyId = Authorization.AuthorizationContext.Current.CompanyId;

            if (returnValue == null)
            {
                objCollection.CommitTransaction(System.Threading.Thread.CurrentThread.ManagedThreadId, companyId);
            }
            else
            {
                if (returnValue.GetType() == typeof(Exception))
                {
                    objCollection.RollbackTransaction(System.Threading.Thread.CurrentThread.ManagedThreadId, companyId);
                }
                else
                {
                    objCollection.CommitTransaction(System.Threading.Thread.CurrentThread.ManagedThreadId, companyId);
                }
            }
        }

        public object BeforeCall(string operationName, object[] inputs)
        {
            int companyId = Authorization.AuthorizationContext.Current.CompanyId;

            TransactionCollection objCollection = new TransactionCollection();
            TransactionCollection objCollection2 = TransactionCollection.GetInstance();

            objCollection2.CreateConnectionTransaction(System.Threading.Thread.CurrentThread.ManagedThreadId, companyId);
            return null;
        }

        #endregion
    }
}
